package com.zhenyi.youqu.miniapp;

import java.util.Date;

import com.cjw.model.DBMap;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.utils.AuthUtils;
import com.utils.interceptor.TestInterceptor;
import com.youqu.common.model.YqApp;
import com.youqu.common.model.YqUser;
import com.zhenyi.core.AES;
import com.zhenyi.core.interceptor.ExceptionInterceptor;
import com.zhenyi.youqu.core.YQMiniAppController;
import com.zhenyi.youqu.core.ZHSMSUtils;
import com.zhenyi.youqu.interceptor.YQUserInterceptor;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class AuthController extends YQMiniAppController {
	private final String CACHE_KEY = "-youqu";
	private final String code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";

	/**
	 * 注册(与原获取手机号接口基本一致,需要再提供微信基本信息)
	 */
	@Clear
	public void register() {
		YqApp app = getApp();
		String openId = getPara("openId");
		if (StrKit.isBlank(openId)) {
			// renderError(401);
			LogKit.warn("no openId");
			renderFailure("no openId");
			return;
		}
		if ("undefined".equals(openId)) {
			// renderError(401);
			LogKit.warn("error openId");
			renderFailure("error openId");
			return;
		}
		String encryptedData = getPara("encryptedData");
		String iv = getPara("iv");

		Cache cache = Redis.use();
		String sessionKey = cache.get(openId + CACHE_KEY);

		String decrypted = AES.de(encryptedData, sessionKey, iv);
		if (decrypted == null) {
			LogKit.warn("error decrypted");
			renderFailure();
			return;
		}
		JSONObject obj = JSONUtil.parseObj(decrypted);
		String phone = obj.getStr("phoneNumber");

		String country = getPara("country");
		Integer gender = getParaToInt("gender", 0);
		String province = getPara("province");
		String avatarUrl = getPara("avatarUrl");
		String nickName = getPara("nickName");

		YqUser wechat = YqUser.dao.findByOpenId(openId);
		if (wechat == null) {
			wechat = new YqUser();
			wechat.setOpenId(openId);
			wechat.setMobile(phone);
			wechat.setProjectAppId(app.getId());
			wechat.save();
		}
		if (StrKit.notBlank(avatarUrl)) {
			wechat.setAvatarUrl(avatarUrl);
		}
		if (StrKit.notBlank(nickName)) {
			wechat.setNickName(nickName);
		}
		if (gender != null) {
			wechat.setGender(gender);
		}
		if (StrKit.notBlank(country)) {
			wechat.setCountry(country);
		}
		if (StrKit.notBlank(province)) {
			wechat.setProvince(province);
		}
		if (StrKit.isBlank(wechat.getCode())) {
			wechat.setCode(HASHID.encode(wechat.getId()));
		}
		wechat.setLastLogin(new Date());
		wechat.setLoginCount(wechat.getLoginCount() == null ? 1 : (wechat.getLoginCount() + 1));
		wechat.update();

		String token = AuthUtils.login(String.valueOf(wechat.getId()), this);
		DBMap map = new DBMap();
		map.put("token", token);
		map.put("user", wechat);
		map.put("openId", wechat.getOpenId());
		map.put("mobile", phone);
		renderSuccess(map);
	}

	/**
	 * 通过code换取openId,仅仅获取openId
	 */
	public void openId() {
		String code = getPara("code");
		if (StrKit.isBlank(code)) {
			renderFailure("code is blank");
			return;
		}
		String appid = "";
		String appSecret = "";
		YqApp app = getApp();
		if (app != null) {
			appid = app.getWechatMiniAppId();
			appSecret = app.getWechatMiniAppSecret();
		} else {
			renderFailure("app error");
			return;
		}
		System.out.println("appid" + appid);
		System.out.println("appSecret" + appSecret);
		String url = StrFormatter.format(code2SessionUrl, appid, appSecret, code);
		String response = HttpKit.get(url);
		JSONObject jsonObject = JSONUtil.parseObj(response);
		String openId = jsonObject.getStr("openid");
		String session_key = jsonObject.getStr("session_key");
		// String unionid = jsonObject.getStr("unionid");
		Integer errcode = jsonObject.getInt("errcode");
		if (errcode != null) {
			System.out.println(url);
			String errmsg = jsonObject.getStr("errmsg");
			LogKit.warn("jscode2session error " + errmsg);
			renderFailure("jscode2session error");
			return;
		}
		YqUser user = YqUser.dao.findByOpenId(openId);
		DBMap map = new DBMap();
		map.put("openId", openId);
		if (user != null) {
			String token = AuthUtils.login(String.valueOf(user.getId()), this);
			map.put("token", token);
			map.put("user", user);
		}
		Cache cache = Redis.use();
		cache.setex(openId + CACHE_KEY, 3600 * 24, session_key);
		renderSuccess(map);

	}

	@Clear
	@Override
	public void index() {
		String code = getPara("code");
		if (StrKit.isBlank(code)) {
			renderFailure();
			return;
		}
		String appid = getPara("appid", "");
		String appSecret = "";
		if (StrKit.isBlank(appid)) {
			appid = YQ_APP_ID;
			appSecret = YQ_APP_SECRET;
		} else {
			appSecret = PropKit.get(appid);
		}
		YqApp app = getApp();
		if (app != null) {
			appid = app.getWechatMiniAppId();
			appSecret = app.getWechatMiniAppSecret();
		}
		String country = getPara("country");
		Integer gender = getParaToInt("gender", 0);
		String province = getPara("province");
		String avatarUrl = getPara("avatarUrl");
		String nickName = getPara("nickName");
		String url = StrFormatter.format(code2SessionUrl, appid, appSecret, code);
		// System.out.println(url);
		String response = HttpKit.get(url);
		// System.out.println(response);
		JSONObject jsonObject = JSONUtil.parseObj(response);
		String openId = jsonObject.getStr("openid");
		String session_key = jsonObject.getStr("session_key");
		String unionid = jsonObject.getStr("unionid");
		Integer errcode = jsonObject.getInt("errcode");
		if (errcode != null) {
			String errmsg = jsonObject.getStr("errmsg");
			LogKit.warn("jscode2session error " + errmsg);
			renderFailure();
			return;
		}
		YqUser wechat = YqUser.dao.findByOpenId(openId);
		// LxUser wechat = LxUser.dao.findByUnionId(unionid);
		if (wechat == null) {
			wechat = new YqUser();
			wechat.setUnionid(unionid);
			wechat.setOpenId(openId);
			wechat.setProjectAppId(app.getId());
			wechat.save();
			// renderFailure("未找到绑定用户");
			// DBMap map = new DBMap();
			// map.put("unionId", unionid);
			// map.put("openId", openId);
			// renderResult(map, "ok", 206);
			// return;
		}

		// if (wechat == null) {
		// wechat = new XhcWechat();
		// wechat.save();
		// wechat.setOpenId(openId);
		// }
		// wechat.setSessionKey(session_key);
		// if (StrKit.notBlank(country)) {
		// wechat.setCountry(country);
		// }
		// if (StrKit.notBlank(province)) {
		// wechat.setProvince(province);
		// }
		if (StrKit.notBlank(avatarUrl)) {
			wechat.setAvatarUrl(avatarUrl);
		}
		if (StrKit.notBlank(nickName)) {
			wechat.setNickName(nickName);
		}
		if (gender != null) {
			wechat.setGender(gender);
		}
		if (StrKit.notBlank(country)) {
			wechat.setCountry(country);
		}
		if (StrKit.notBlank(province)) {
			wechat.setProvince(province);
		}
		if (StrKit.isBlank(wechat.getCode())) {
			wechat.setCode(HASHID.encode(wechat.getId()));
		}
		// wechat.setNickName(nickName);
		// wechat.setAppid(APP_ID);
		wechat.setLastLogin(new Date());
		wechat.setLoginCount(wechat.getLoginCount() == null ? 1 : (wechat.getLoginCount() + 1));
		wechat.update();
		DBMap map = new DBMap();
		String token = AuthUtils.login(String.valueOf(wechat.getId()), this);
		map.put("token", token);
		map.put("user", wechat);
		map.put("openId", wechat.getOpenId());
		// map.put("unionId", wechat.getUnionId());

		Cache cache = Redis.use();
		cache.setex(openId + CACHE_KEY, 3600 * 24, session_key);

		renderSuccess(map);

	}

	public void getPhoneNumber() {
		String encryptedData = getPara("encryptedData");
		String iv = getPara("iv");
		String openId = getPara("openId");

		Cache cache = Redis.use();
		String sessionKey = cache.get(openId + CACHE_KEY);

		String decrypted = AES.de(encryptedData, sessionKey, iv);
		if (decrypted == null) {
			System.out.println("sessionKey: " + sessionKey);
			System.out.println("openId: " + openId);
			renderFailure();
			return;
		}
		JSONObject obj = JSONUtil.parseObj(decrypted);
		String phone = obj.getStr("phoneNumber");

		renderSuccess(phone);
	}

	/**
	 * 微信登录
	 * 
	 * @Time 2019年3月5日 上午1:17:30
	 */
	public void wechat() {
	}

	public void logout() {
		String token = getPara("token");
		boolean flag = AuthUtils.logout(this);
		renderFlag(flag);
	}

	/**
	 * 持续登录,换取code,下次用code再次登录
	 * 
	 * @Time 2019年3月24日 下午10:54:16
	 */
	@Before({ YQUserInterceptor.class, ExceptionInterceptor.class })
	public void keep() {
		String token = getPara("token");
		String code = DigestUtil.md5Hex(token);
		YqUser user = getUser();
		user.setToken(code);
		user.update();
		renderSuccess(code);
	}

	/**
	 * 持续登录
	 * 
	 * @Time 2019年3月24日 下午10:54:45
	 */
	@Clear
	public void persist() {
		String code = getPara("code");
		if (StrKit.isBlank(code)) {
			renderFailure("登录失败");
			return;
		}
		YqUser user = YqUser.dao.searchFirst("token", code);
		if (user == null) {
			renderFailure("登录失败.");
			return;
		}
		String token = AuthUtils.login(String.valueOf(user.getId()), this);
		renderSuccess(token);
	}

	@Clear
	@Before(TestInterceptor.class)
	public void debug() {
		YqUser user = YqUser.dao.findById(17);
		String token = AuthUtils.login(String.valueOf(user.getId()), this);
		System.out.println("token: " + token);
		renderSuccess(token);
	}

	/**
	 * 手机号登录
	 * 
	 * @Time 2019年3月5日 上午1:17:36
	 */
	public void login() {
		YqApp app = getApp();
		String mobile = getPara("mobile");
		if (StrKit.isBlank(mobile)) {
			renderMsg("请输入手机号");
			return;
		}
		String code = getPara("code");
		if (StrKit.isBlank(code)) {
			renderMsg("请输入验证码");
			return;
		}
		boolean isDebug = "13631290232".equals(mobile) && "123456".equals(code);
		if (isDebug) {
			YqUser user = YqUser.dao.findById(17);
			String token = AuthUtils.login(String.valueOf(user.getId()), this);
			System.out.println("token: " + token);
			renderSuccess(token);
			return;
		}
		ZHSMSUtils zhsmsUtils = new ZHSMSUtils();
		if (!isDebug && !zhsmsUtils.verify(mobile, code)) {
			renderFailure("验证码错误");
			return;
		}
		YqUser user = YqUser.dao.findByMobile(mobile);
		if (user == null) {
			user = new YqUser();
			user.setMobile(mobile);
			user.setProjectAppId(app.getId());
			user.save();
		}
		user.setLastLogin(new Date());
		user.update();
		String token = AuthUtils.login(String.valueOf(user.getId()), this);
		renderSuccess(token);
	}

}
